package io.github.bigbird0101.yousishi.sql.print;

import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.LoaderClassPath;

import java.util.Objects;

/**
 * <p> MySqlAdapter </p>
 *
 * @author fupengpeng
 * @version 1.0
 * @date 2025/6/20 9:30
 */
public class NewMySqlAdapter extends AbstractPrintSql {
    private static final String CLASS_NAME_ABSTRACT_PREPARED_QUERY = "com.mysql.cj.AbstractPreparedQuery";
    private static final String CLASS_NAME_QUERY_BINDINGS = "com.mysql.cj.QueryBindings";
    private static final String METHOD_NAME_FILL_SEND_PACKET = "fillSendPacket";

    @Override
    public boolean match(String className) {
        boolean equals = CLASS_NAME_ABSTRACT_PREPARED_QUERY.equals(className) ||
                CLASS_NAME_ABSTRACT_PREPARED_QUERY.equals(className.replaceAll("/", "."));
        if (equals) {
            System.out.println("匹配到com.mysql.cj.AbstractPreparedQuery Agent的sql打印注入");
        }
        return equals;
    }

    @Override
    public byte[] doPrintSqlClass(ClassLoader classLoader, Boolean isFormatSql) {
        try {
            ClassPool classPool = ClassPool.getDefault();
            classPool.appendClassPath(new LoaderClassPath(classLoader));
            CtClass ctClass = classPool.get(CLASS_NAME_ABSTRACT_PREPARED_QUERY.replaceAll("/", "."));
            ctClass.addMethod(getPrintSqlMethod(ctClass));
            final CtClass queryBindingsCtClass = classPool.get(CLASS_NAME_QUERY_BINDINGS);
            final CtMethod fillSendPacketCtMethod = ctClass.getDeclaredMethod(METHOD_NAME_FILL_SEND_PACKET,
                    new CtClass[]{queryBindingsCtClass});
            if (Objects.nonNull(fillSendPacketCtMethod)) {
                fillSendPacketCtMethod.insertBefore("{davaPrintSql(asSql()," + isFormatSql + ");}");
            }
            return ctClass.toBytecode();
        } catch (Exception exception) {
            System.err.println(exception);
            throw new RuntimeException(exception);
        }
    }
}
